programming4us
           
 
 
Programming

Microsoft ASP.NET 3.5 : Writing HTTP Handlers (part 5) - Advanced HTTP Handler Programming

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
5/17/2012 3:55:49 PM

Advanced HTTP Handler Programming

HTTP handlers are not a tool for everybody. They serve a very neat purpose: changing the way a particular resource, or set of resources, is served to the user. You can use handlers to filter out resources based on runtime conditions or to apply any form of additional logic to the retrieval of traditional resources such as pages and images. Finally, you can use HTTP handlers to serve certain pages or resources in an asynchronous manner.

For HTTP handlers, the registration step is key. Registration enables ASP.NET to know about your handler and its purpose. Registration is required for two practical reasons. First, it serves to ensure that IIS forwards the call to the correct ASP.NET application. Second, it serves to instruct your ASP.NET application on the class to load to “handle” the request. As mentioned, you can use handlers to override the processing of existing resources (for example, hello.aspx) or to introduce new functionalities (for example, folder.axd). In both cases, you’re invoking a resource whose extension is already known to IIS—the .axd extension is registered in the IIS metabase when you install ASP.NET. In both cases, though, you need to modify the web.config file of the application to let the application know about the handler.

By using the ASHX extension and programming model for handlers, you can also save yourself the web.config update and deploy a new HTTP handler by simply copying a new file in a new or existing application’s folder.

Deploying Handlers as ASHX Resources

An alternative way to define an HTTP handler is through an .ashx file. The file contains a special directive, named @WebHandler, that expresses the association between the HTTP handler endpoint and the class used to implement the functionality. All .ashx files must begin with a directive like the following one:

<%@ WebHandler Language="C#" Class="Core35.Components.YourHandler" %>

When an .ashx endpoint is invoked, ASP.NET parses the source code of the file and figures out the HTTP handler class to use from the @WebHandler directive. This automation removes the need of updating the web.config file. Here’s a sample .ashx file. As you can see, it is the plain class file plus the special @WebHandler directive:

<%@ WebHandler Language="C#" Class="MyHandler" %>

using System.Web;

public class MyHandler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");
    }
    public bool IsReusable {
        get {
            return false;
        }
    }
}

Note that the source code of the class can either be specified inline or loaded from any of the assemblies referenced by the application. When .ashx resources are used to implement an HTTP handler, you just deploy the source file, and you’re done. Just as for XML Web services, the source file is loaded and compiled only on demand. Because ASP.NET adds a special entry to the IIS metabase for .ashx resources, you don’t even need to enter changes to the Web server configuration.

Resources with an .ashx extension are handled by an HTTP handler class named SimpleHandleFactory. Note that SimpleHandleFactory is actually an HTTP handler factory class, not a simple HTTP handler class. We’ll discuss handler factories in a moment.

The SimpleHandleFactory class looks for the @WebHandler directive at the beginning of the file. The @WebHandler directive tells the handler factory the name of the HTTP handler class to instantiate once the source code has been compiled.

Important

You can build HTTP handlers both as regular class files compiled to an assembly and via .ashx resources. There’s no significant difference between the two approaches except that .ashx resources, like ordinary ASP.NET pages, will be compiled on the fly upon the first request.


Prevent Access to Forbidden Resources

If your Web application manages resources of a type that you don’t want to make publicly available over the Web, you must instruct IIS not to display those files. A possible way to accomplish this consists of forwarding the request to aspnet_isapi and then binding the extension to one of the built-in handlers—the HttpForbiddenHandler class:

<add verb="*" path="*.xyz" type="System.Web.HttpForbiddenHandler" />

Any attempt to access an .xyz resource results in an error message being displayed. The same trick can also be applied for individual resources served by your application. If you need to deploy, say, a text file but do not want to take the risk that somebody can get to them, add the following:

<add verb="*" path="yourFile.txt" type="System.Web.HttpForbiddenHandler" />

Should It Be Reusable or Not?

In a conventional HTTP handler, the ProcessRequest method takes the lion’s share of the overall set of functionality. The second member of the IHttpHandler interface—the IsReusable property—is used only in particular circumstances. If you set the IsReusable property to return true, the handler is not unloaded from memory after use and is repeatedly used. Put another way, the Boolean value returned by IsReusable indicates whether the handler object can be pooled.

Frankly, most of the time it doesn’t really matter what you return—be it true or false. If you set the property to return false, you require that a new object be allocated for each request. The simple allocation of an object is not a particularly expensive operation. However, the initialization of the handler might be costly. In this case, by making the handler reusable, you save much of the overhead. If the handler doesn’t hold any state, there’s no reason for not making it reusable.

In summary, I’d say that IsReusable should be always set to true, except when you have instance properties to deal with or properties that might cause trouble if used in a concurrent environment. If you have no initialization tasks, it doesn’t really matter whether it returns true or false. As a margin note, the System.Web.UI.Page class—the most popular HTTP handler ever—sets its IsReusable property to false.

The key point to make is the following. Who’s really using IsReusable and, subsequently, who really cares about its value?

Once the HTTP runtime knows the HTTP handler class to serve a given request, it simply instantiates it—no matter what. So when is the IsReusable property of a given handler taken into account? Only if you use an HTTP handler factory—that is, a piece of code that dynamically decides which handler should be used for a given request. An HTTP handler factory can query a handler to determine whether the same instance can be used to service multiple requests and thus optionally create and maintain a pool of handlers.

ASP.NET pages and ASHX resources are served through factories. However, none of these factories ever checks IsReusable. Of all the built-in handler factories in the whole ASP.NET platform, very few check the IsReusable property of related handlers. So what’s the bottom line?

As long as you’re creating HTTP handlers for AXD, ASHX, or perhaps ASPX resources, be aware that the IsReusable property is blissfully ignored. Do not waste your time trying to figure out the optimal configuration. Instead, if you’re creating an HTTP handler factory to serve a set of resources, whether or not to implement a pool of handlers is up to you and IsReusable is the perfect tool for the job.

But when should you employ an HTTP handler factory? In all situations in which the HTTP handler class for a request is not uniquely identified. For example, for ASPX pages, you don’t know in advance which HTTP handler type you have to use. The type might not even exist (in which case, you compile it on the fly). The HTTP handler factory is used whenever you need to apply some logic to decide which is the right handler to use. In other words, you need an HTTP handler factory when declarative binding between endpoints and classes is not enough.

HTTP Handler Factories

An HTTP request can be directly associated with an HTTP handler or with an HTTP handler factory object. An HTTP handler factory is a class that implements the IHttpHandlerFactory interface and is in charge of returning the actual HTTP handler to use to serve the request. The SimpleHandlerFactory class provides a good example of how a factory works. The factory is mapped to requests directed at .ashx resources. When such a request comes in, the factory determines the actual handler to use by looking at the @WebHandler directive in the source file.

In the .NET Framework, HTTP handler factories are used to perform some preliminary tasks on the requested resource prior to passing it on to the handler. Another good example of a handler factory object is represented by an internal class named PageHandlerFactory, which is in charge of serving .aspx pages. In this case, the factory handler figures out the name of the handler to use and, if possible, loads it up from an existing assembly.

HTTP handler factories are classes that implement a couple of methods on the IHttpHandlerFactory interface—GetHandler and ReleaseHandler, as shown in Table 3.

Table 3. Members of the IHttpHandlerFactory Interface
MethodDescription
GetHandlerReturns an instance of an HTTP handler to serve the request
ReleaseHandlerTakes an existing HTTP handler instance and frees it up or pools it

The GetHandler method has the following signature:

public virtual IHttpHandler GetHandler(HttpContext context,
    string requestType, string url, string pathTranslated);

The requestType argument is a string that evaluates to GET or POST—the HTTP verb of the request. The last two arguments represent the raw URL of the request and the physical path behind it. The ReleaseHandler method is a mandatory override for any class that implements IHttpHandlerFactory; in most cases, it will just have an empty body.

The following listing shows a sample HTTP handler factory that returns different handlers based on the HTTP verb (GET or POST) used for the request:

class MyHandlerFactory : IHttpHandlerFactory
{
    public IHttpHandler GetHandler(HttpContext context,
        string requestType, String url, String pathTranslated)
    {
        // Feel free to create a pool of HTTP handlers here
        if(context.Request.RequestType.ToLower() == "get")
            return (IHttpHandler) new MyGetHandler();
        else if(context.Request.RequestType.ToLower() == "post")
            return (IHttpHandler) new MyPostHandler();
        return null;
    }

    public void ReleaseHandler(IHttpHandler handler)
    {
        // Nothing to do
    }
}

When you use an HTTP handler factory, it’s the factory, not the handler, that needs to be registered with the ASP.NET configuration file. If you register the handler, it will always be used to serve requests. If you opt for a factory, you have a chance to decide dynamically and based on runtime conditions which handler is more appropriate for a certain request. In doing so, you can use the IsReusable property of handlers to implement a pool.

Asynchronous Handlers

An asynchronous HTTP handler is a class that implements the IHttpAsyncHandler interface. The system initiates the call by invoking the BeginProcessRequest method. Next, when the method ends, a callback function is automatically invoked to terminate the call. In the .NET Framework, the sole HttpApplication class implements the asynchronous interface. The members of IHttpAsyncHandler interface are shown in Table 4.

Table 4. Members of the IHttpAsyncHandler Interface
MethodDescription
BeginProcessRequestInitiates an asynchronous call to the specified HTTP handler
EndProcessRequestTerminates the asynchronous call

The signature of the BeginProcessRequest method is as follows:

IAsyncResult BeginProcessRequest(HttpContext context,
    AsyncCallback cb, object extraData);

The context argument provides references to intrinsic server objects used to service HTTP requests. The second parameter is the AsyncCallback object to invoke when the asynchronous method call is complete. The third parameter is a generic cargo variable that contains any data you might want to pass to the handler.

Note

An AsyncCallback object is a delegate that defines the logic needed to finish processing the asynchronous operation. A delegate is a class that holds a reference to a method. A delegate class has a fixed signature, and it can hold references only to methods that match that signature. A delegate is equivalent to a type-safe function pointer or a callback. As a result, an AsyncCallback object is just the code that executes when the asynchronous handler has completed its job.


The AsyncCallback delegate has the following signature:

public delegate void AsyncCallback(IAsyncResult ar);

It uses the IAsyncResult interface to obtain the status of the asynchronous operation. To illustrate the plumbing of asynchronous handlers, I’ll show you the pseudocode that the HTTP runtime employs when it deals with asynchronous handlers. The HTTP runtime invokes the BeginProcessRequest method as illustrated by the following pseudocode:

// Sets an internal member of the HttpContext class with
// the current instance of the asynchronous handler
context.AsyncAppHandler = asyncHandler;

// Invokes the BeginProcessRequest method on the asynchronous HTTP handler
asyncHandler.BeginProcessRequest(context, OnCompletionCallback, context);

The context argument is the current instance of the HttpContext class and represents the context of the request. A reference to the HTTP context is also passed as the custom data sent to the handler to process the request. The extraData parameter in the BeginProcessRequest signature is used to represent the status of the asynchronous operation. The BeginProcessRequest method returns an object of type HttpAsyncResult—a class that implements the IAsyncResult interface. The IAsyncResult interface contains a property named AsyncState that is set with the extraData value—in this case, the HTTP context.

The OnCompletionCallback method is an internal method. It gets automatically triggered when the asynchronous processing of the request terminates. The following listing illustrates the pseudocode of the HttpRuntime private method:

// The method must have the signature of an AsyncCallback delegate
private void OnHandlerCompletion(IAsyncResult ar)
{
    // The ar parameter is an instance of HttpAsyncResult
    HttpContext context = (HttpContext) ar.AsyncState;

    // Retrieves the instance of the asynchronous HTTP handler
    // and completes the request
    IHttpAsyncHandler asyncHandler = context.AsyncAppHandler;
    asyncHandler.EndProcessRequest(ar);

    // Finalizes the request as usual
    ...
}

The completion handler retrieves the HTTP context of the request through the AsyncState property of the IAsyncResult object it gets from the system. As mentioned, the actual object passed is an instance of the HttpAsyncResult class—in any case, it is the return value of the BeginProcessRequest method. The completion routine extracts the reference to the asynchronous handler from the context and issues a call to the EndProcessRequest method:

void EndProcessRequest(IAsyncResult result);

The EndProcessRequest method takes the IAsyncResult object returned by the call to BeginProcessRequest. As implemented in the HttpApplication class, the EndProcessRequest method does nothing special and is limited to throwing an exception if an error occurred.

Implementing Asynchronous Handlers

Asynchronous handlers essentially serve one particular scenario—when the generation of the markup is subject to lengthy operations, such as time-consuming database stored procedures or calls to Web services. In these situations, the ASP.NET thread in charge of the request is stuck waiting for the operation to complete. Because the thread is a valuable member of the ASP.NET thread pool, lengthy tasks are potentially the perfect scalability killer. However, asynchronous handlers are here to help.

The idea is that the request begins on a thread-pool thread, but that thread is released as soon as the operation begins. In BeginProcessRequest, you typically create your own thread and start the lengthy operation. BeginProcessRequest doesn’t wait for the operation to complete; therefore, the thread is returned to the pool immediately.

There are a lot of tricky details that this bird’s-eye description just omitted. In the first place, you should strive to avoid a proliferation of threads. Ideally, you should use a custom thread pool. Furthermore, you must figure out a way to signal when the lengthy operation has terminated. This typically entails creating a custom class that implements IAsyncResult and returning it from BeginProcessRequest. This class embeds a synchronization object—typically a ManualResetEvent object—that the custom thread carrying the work will signal upon completion.

In the end, building asynchronous handlers is definitely tricky and not for novice developers. Very likely, you are more interested in asynchronous pages than in asynchronous HTTP handlers—that is, the same mechanism but applied to .aspx resources. In this case, the “lengthy task” is merely the ProcessRequest method of the Page class. (Obviously, you configure the page to execute asynchronously only if the page contains code that might start I/O-bound and potentially lengthy operations.)

Warning

I’ve seen several ASP.NET developers using an .aspx page to serve markup other than HTML markup. This is not a good idea. An .aspx resource is served by quite a rich and sophisticated HTTP handler—the System.Web.UI.Page class. The ProcessRequest method of this class entirely provides for the page life cycle as we know it—Init, Load, and PreRender events, as well as rendering stage, view state, and postback management. Nothing of the kind is really required if you only need to retrieve and return, say, the bytes of an image.

Other -----------------
- Microsoft ASP.NET 3.5 : HTTP Handlers and Modules - Quick Overview of the IIS Extensibility API
- Programming WCF Services : Queued Services - The HTTP Bridge
- Microsoft ASP.NET 4 : Ajax - Extender Controls (part 2) - A Modal Pop-up Dialog-Style Component
- Microsoft ASP.NET 4 : Ajax - Extender Controls (part 1) - The AutoComplete Extender
- Mobile Handheld Devices : DATA SYNCHRONIZATION
- Mobile Handheld Devices : MEMORY, STORAGE AND BATTERIES
- LINQ to Objects : How to Return Elements When the Result Is a Sequence (Select Many)
- LINQ to Objects : How to Change the Return Type (Select Projection)
- A Technical Overview of the Mobile Web : OTHER MOBILE TECHNOLOGIES
- A Technical Overview of the Mobile Web : THE MOBILE NETWORK
- Programming WCF Services : The Response Service (part 4) - Transactions
- Programming WCF Services : The Response Service (part 3) - Queued Service-Side Programming & Response Service-Side Programming
- Programming WCF Services : The Response Service (part 2) - Client-Side Programming
- Programming WCF Services : The Response Service (part 1) - Designing a Response Service Contract
- Programming WCF Services : Queued Versus Connected Calls - Requiring Queuing
- Programming WCF Services : Queued Services - Playback Failures
- DotNetNuke Skinning : Package and Deploy
- Unit Testing in Visual Studio 2010 (part 2) - Running a battery of tests
- Unit Testing in Visual Studio 2010 (part 1) - Creating unit tests
- Microsoft ASP.NET 3.5 : AJAX-Enabled Web Services - Remote Calls via Page Methods
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us